package com.pug.security.file;

import com.alibaba.fastjson.JSON;
import com.pug.security.config.SecurityConfig04;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
import xq.pug.common.exception.errorType.SystemErrorType;
import xq.pug.common.jwt.JwtUtils;
import xq.pug.common.result.R;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Arrays;
import java.util.Objects;

/**
 * @author RenGaoshuai
 * @date 2023/7/19 13:37
 * @description 自定义token拦截器
 */
@Component
@Slf4j
public class JwtAuthenticationFilter extends OncePerRequestFilter {

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
        log.info("进入jwt拦截器");

        String token = request.getHeader("token");
        if (Arrays.asList(SecurityConfig04.AUTH_WHITELIST).contains(request.getRequestURI())) {
            log.info("白名单接口，放行");
            chain.doFilter(request, response);
            return;
        }
        if (StringUtils.isBlank(token)) {
            log.error("token为空");
            response.setCharacterEncoding("UTF-8");
            response.setContentType("application/json");
            response.getWriter().write(JSON.toJSONString(R.ofFail(SystemErrorType.BLANK_TOKEN)));
            return;
        }

        if (!JwtUtils.validateToken(token)) {
            //token 不合法
            log.error("token不合法");
            response.setCharacterEncoding("UTF-8");
            response.setContentType("application/json");
            response.getWriter().write(JSON.toJSONString(R.ofFail(SystemErrorType.INVALID_TOKEN)));
            return;
        }

        if (JwtUtils.isTokenExpired(token)) {
            log.error("token过期");
            response.setCharacterEncoding("UTF-8");
            response.setContentType("application/json");
            response.getWriter().write(JSON.toJSONString(R.ofFail(SystemErrorType.TIMEOUT_TOKEN)));
            return;
        }

        Claims claimsFromToken = JwtUtils.getClaimsFromToken(token);
        String username = (String) claimsFromToken.get("username");

        if (StringUtils.isNotBlank(username) && Objects.isNull(SecurityContextHolder.getContext().getAuthentication())) {
            //验证通过
            UsernamePasswordAuthenticationToken authenticationToken =
                    new UsernamePasswordAuthenticationToken(username, null, null);

            authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
            SecurityContextHolder.getContext().setAuthentication(authenticationToken);
        }
        chain.doFilter(request, response);

    }
}
